#include "Ogre.h"
#include "OIS.h"

#include "EngineManager.h"
#include "EntityManager.h"
#include "InputHandler.h"
#include "Player.h"

Player::Player() : Input(NULL), MoveVector(0,0,0){ } //we define the constructor and destructor
Player::~Player(){ }

bool Player::Startup(SceneManager *sceneMgr, InputHandler *input, Simulation *sim)
{
	mSceneMgr = sceneMgr;	
	mRaySceneQry = mSceneMgr->createRayQuery(Ray());

	//SceneManager* sceneMgr = root->getSceneManager("DEFAULT");
	//initialise the MainNode (the one the player uses as a base)
	MainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("MainNode"); // create a new SceneNode as a child of the root node

	MainNode->lookAt(Ogre::Vector3::ZERO, Ogre::Node::TS_LOCAL);
   
	//initialise the EyeNode (for the camera)
	EyeNode = MainNode->createChildSceneNode("EyeNode", Ogre::Vector3(0, 20, 0)); //now create another SceneNode as a child of the MainNode
	
	//wrap the camera in the main scene with the EyeNode, so the camera now a child of it
	EyeNode->attachObject(mSceneMgr->getCamera("camera"));	//this makes the camera move with the EyeNode
	
	MainNode->setPosition(Ogre::Vector3(300,0,0));
	//grab a reference of the InputHandler and store it in the player
	Input = input;

	Sim = sim;
	Sim->requestStateChange(SIM_SIMULATION);

	OgreEngineManager::Instance().GetRoot()->addFrameListener(this);
	return true;
}

bool Player::frameStarted(const FrameEvent &evt)
{
	OIS::Keyboard *mKeyboard = Input->GetKeyboard();
	OIS::MouseState mMouseState = Input->GetMouse()->getMouseState();

	if(Sim->getCurrentState()==SIM_SIMULATION)
	{
		EyeNode->pitch(Ogre::Radian(mMouseState.Y.rel) * -0.005); // * evt.timeSinceLastFrame
		MainNode->yaw(Ogre::Radian( mMouseState.X.rel) * -0.005); // * evt.timeSinceLastFrame
		
		//reset a vector to be blank
		MoveVector = Ogre::Vector3::ZERO;
		
		mToggleNoclip -= evt.timeSinceLastFrame;
		
		if((mToggleNoclip < 0.0f ) && mKeyboard->isKeyDown(OIS::KC_V))
		{
		   mToggleNoclip  = 0.5;
		   NOCLIP = !NOCLIP;
		}

		if (mKeyboard->isKeyDown(OIS::KC_W))
			MoveVector += Ogre::Vector3::UNIT_Z; //add on UNIT_Z

		if (mKeyboard->isKeyDown(OIS::KC_A))
			MoveVector += Ogre::Vector3::UNIT_X; //add on UNIT_X	

		if (mKeyboard->isKeyDown(OIS::KC_S))
			MoveVector -= Ogre::Vector3::UNIT_Z; //add on NEGATIVE_UNIT_Z

		if (mKeyboard->isKeyDown(OIS::KC_D))
			MoveVector -= Ogre::Vector3::UNIT_X; //add on NEGATIVE_UNIT_X
		
		if(NOCLIP)
			MoveVector = EyeNode->getOrientation() * MoveVector; //rotate the MoveVector based on the EyeNode's pitch
		
		//then rotate that rotated MoveVector based on the MainNode's yaw
		MoveVector = MainNode->getOrientation() * MoveVector;

		if (mKeyboard->isKeyDown(OIS::KC_SPACE) & NOCLIP)
			MoveVector -= Ogre::Vector3::UNIT_Y;

		if (mKeyboard->isKeyDown(OIS::KC_LSHIFT))
			MOVE_SPEED = 200;
		else
			MOVE_SPEED = 100;
		
		MainNode->translate(MoveVector.normalisedCopy() * MOVE_SPEED * -evt.timeSinceLastFrame);
	}

	return true;
}

void Player::InjectMouse(OIS::MouseButtonID btn, bool Pressed)
{
	Camera *mCamera = mSceneMgr->getCamera("camera");

	switch(btn)
	{
		case OIS::MB_Left:
			if(Pressed && Sim->getCurrentState()==SIM_SIMULATION)
			{
				EntityManager::Instance().AddEntity(
					mCamera->getDerivedPosition() + mCamera->getDerivedDirection() * 10,
					mCamera->getDerivedDirection().normalisedCopy() * 7.0f,
					EntityManager::SHAPE_BOX
				);
			}
			break;
		case OIS::MB_Right:
			if(Pressed)
			{
				/*Ray r(mCamera->getDerivedDirection().normalisedCopy(), mCamera->getDerivedPosition());

				mRaySceneQry->setRay(r);
				mRaySceneQry->setSortByDistance(true);

				RaySceneQueryResult &result = mRaySceneQry->execute();
				RaySceneQueryResult::iterator itr = result.begin();
				if (itr != result.end() && itr->movable)
				{
					if(itr->movable->getName()!="GroundEntity")
						itr->movable->setVisible(false);
				}*/
			}
			break;
		default:
			break;
	}
}

void Player::Shutdown()
{
}